
package com.bluelinelabs.conductor.conductor;

import ohos.aafwk.content.IntentParams;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;

/**
 * lipeiquan
 *
 * @since 2021-05-06
 */
public class Backstack implements Iterable<RouterTransaction> {

    private static final String KEY_ENTRIES = "Backstack.entries";

    private final Deque<RouterTransaction> backstack = new ArrayDeque<>();

    @SuppressWarnings("BooleanMethodIsAlwaysInverted")
    boolean isEmpty() {
        return backstack.isEmpty();
    }

    void restoreInstanceState(IntentParams savedInstanceState) {
        ArrayList<IntentParams> entryBundles = (ArrayList<IntentParams>) savedInstanceState.getParam(KEY_ENTRIES);
        if (entryBundles != null) {
            Collections.reverse(entryBundles);
            for (IntentParams transactionBundle : entryBundles) {
                backstack.push(new RouterTransaction(transactionBundle));
            }
        }
    }

    Iterator<RouterTransaction> reverseIterator() {
        return backstack.descendingIterator();
    }

    int size() {
        return backstack.size();
    }

    @Override
    public Iterator<RouterTransaction> iterator() {
        return backstack.iterator();
    }

    RouterTransaction peek() {
        return backstack.peek();
    }

    boolean contains(Controller controller) {
        for (RouterTransaction transaction : backstack) {
            if (controller == transaction.controller) {
                return true;
            }
        }
        return false;
    }

    void push(RouterTransaction transaction) {
        backstack.push(transaction);
    }

    RouterTransaction root() {
        return backstack.size() > 0 ? backstack.getLast() : null;
    }

    List<RouterTransaction> popAll() {
        List<RouterTransaction> list = new ArrayList<>();
        while (!isEmpty()) {
            list.add(pop());
        }
        return list;
    }

    RouterTransaction pop() {
        RouterTransaction popped = backstack.pop();
        popped.controller.destroy();
        return popped;
    }


    void setBackstack(List<RouterTransaction> backstack) {
        this.backstack.clear();
        for (RouterTransaction transaction : backstack) {
            this.backstack.push(transaction);
        }
    }


    void saveInstanceState(IntentParams outState) {
        ArrayList<IntentParams> entryBundles = new ArrayList<>(backstack.size());
        for (RouterTransaction entry : backstack) {
            entryBundles.add(entry.saveInstanceState());
        }

        outState.setParam(KEY_ENTRIES, entryBundles);
    }
}
